<template>
  <div class="dcf-container">
    <div class="dcf-header">
      <h1>现金流估值 (DCF方法)</h1>
      <p class="dcf-description">
        使用贴现现金流法评估公司价值，通过预测未来现金流并折现到现值来计算公司内在价值
      </p>
    </div>

    <div class="dcf-content">
      <!-- 输入表单 -->
      <div class="input-section">
        <h2>基础数据输入</h2>
        
        <div class="form-grid">
          <div class="form-group">
            <label>首期现金流（万元）</label>
            <input 
              v-model.number="formData.currentFCF" 
              type="number" 
              placeholder="请输入首期现金流"
              class="form-input"
            >
          </div>

          <div class="form-group">
            <label>现金流增长率（%）</label>
            <input 
              v-model.number="formData.growthRate" 
              type="number" 
              step="0.1"
              placeholder="请输入现金流增长率"
              class="form-input"
            >
          </div>

          <div class="form-group">
            <label>可增长年限（年）</label>
            <input 
              v-model.number="formData.forecastYears" 
              type="number" 
              placeholder="请输入可增长年限"
              class="form-input"
            >
          </div>

          <div class="form-group">
            <label>折现率（%）</label>
            <input 
              v-model.number="formData.discountRate" 
              type="number" 
              step="0.1"
              placeholder="请输入折现率"
              class="form-input"
            >
          </div>

          <div class="form-group">
            <label>永续增长率（%）</label>
            <input 
              v-model.number="formData.terminalGrowthRate" 
              type="number" 
              step="0.1"
              placeholder="请输入永续增长率"
              class="form-input"
            >
          </div>
        </div>

        <div class="form-actions">
          <button @click="calculateDCF" class="btn-main">计算估值</button>
          <button @click="resetForm" class="btn-secondary">重置表单</button>
          <button @click="saveToHistory" class="btn-secondary">保存本次计算</button>
          <button @click="loadHistory" class="btn-secondary">加载历史记录</button>
        </div>
      </div>

      <!-- 计算结果 -->
      <div v-if="showResults" class="results-section">
        <h2>估值结果</h2>
        
        <div class="results-grid">
          <div class="result-card primary">
            <div class="result-value-row">
              <span class="result-title">企业价值 (EV)</span>
              <span class="result-value">{{ formatCurrency(valuationResults.enterpriseValue) }}</span>
              <span class="result-label">万元</span>
            </div>
          </div>
        </div>

        <!-- 现金流预测表 -->
        <div class="cashflow-table">
          <h3>计算过程</h3>
          <div class="table-container">
            <table>
              <thead>
                <tr>
                  <th>时间</th>
                  <th>自由现金流（万元）</th>
                  <th>折现因子</th>
                  <th>现值（万元）</th>
                  <th>计算公式</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="(year, index) in valuationResults.cashflowProjection" :key="index">
                  <td>第{{ index + 1 }}年底</td>
                  <td>{{ formatCurrency(year.fcf) }}</td>
                  <td>{{ year.discountFactor.toFixed(2) }}</td>
                  <td>{{ formatCurrency(year.presentValue) }}</td>
                  <td>{{ year.formula }}</td>
                </tr>
                <tr>
                  <td>永续价值</td>
                  <td>{{ formatCurrency(valuationResults.terminalFCF) }}</td>
                  <td></td>
                  <td></td>
                  <td>{{ valuationResults.terminalFormula }}</td>
                </tr>
                <tr>
                  <td>永续现值</td>
                  <td></td>
                  <td></td>
                  <td>{{ formatCurrency(valuationResults.terminalValuePresent) }}</td>
                  <td>{{ valuationResults.terminalPresentFormula }}</td>
                </tr>
                <tr>
                  <td>企业价值</td>
                  <td></td>
                  <td></td>
                  <td>{{ formatCurrency(valuationResults.enterpriseValue) }}</td>
                  <td>{{ valuationResults.enterpriseValueFormula }}</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>

        <div ref="chartRef" style="width:100%;height:320px;margin-top:24px;"></div>
      </div>
    </div>

    <div v-if="showHistory" class="history-modal">
      <div class="history-content">
        <h3>历史记录</h3>
        <ul class="history-list">
          <li v-for="(item, idx) in historyList" :key="idx">
            <div class="history-time">{{ item.time }}</div>
            <div class="history-params">
              <span>首期现金流：</span>{{ item.params.currentFCF }}，
              <span>现金流增长率：</span>{{ item.params.growthRate }}%，
              <span>可增长年限：</span>{{ item.params.forecastYears }}年，
              <span>折现率：</span>{{ item.params.discountRate }}%，
              <span>永续增长率：</span>{{ item.params.terminalGrowthRate }}%
            </div>
            <div class="history-btns">
              <button @click="applyHistory(item)" class="btn-hist">加载</button>
              <button @click="deleteHistory(idx)" class="btn-hist btn-hist-del">删除</button>
            </div>
          </li>
        </ul>
        <button @click="showHistory=false" class="btn-hist btn-hist-close">关闭</button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, nextTick, watch } from 'vue'
import * as echarts from 'echarts'

// 表单数据
const formData = reactive({
  currentFCF: null,
  growthRate: null,
  forecastYears: null,
  discountRate: null,
  terminalGrowthRate: null
})

// 结果数据
const showResults = ref(false)
const valuationResults = ref({})

const chartRef = ref(null)
let chartInstance = null

const historyList = ref([])
const showHistory = ref(false)

function renderChart() {
  if (!chartRef.value || !valuationResults.value.cashflowProjection) return
  if (!chartInstance) {
    chartInstance = echarts.init(chartRef.value)
  }
  const years = valuationResults.value.cashflowProjection.map((_, idx) => `第${idx+1}年底`)
  const fcfArr = valuationResults.value.cashflowProjection.map(item => Number(item.fcf.toFixed(2)))
  const pvArr = valuationResults.value.cashflowProjection.map(item => Number(item.presentValue.toFixed(2)))
  chartInstance.setOption({
    tooltip: { trigger: 'axis' },
    legend: { data: ['自由现金流', '现值'] },
    xAxis: { type: 'category', data: years },
    yAxis: { type: 'value', name: '万元' },
    series: [
      { name: '自由现金流', type: 'line', data: fcfArr, smooth: true, symbol: 'circle', lineStyle: { width: 3, color: '#4f8cff' } },
      { name: '现值', type: 'line', data: pvArr, smooth: true, symbol: 'circle', lineStyle: { width: 3, color: '#10b981' } }
    ]
  })
}

watch(() => valuationResults.value.cashflowProjection, () => {
  nextTick(() => renderChart())
})

onMounted(() => {
  nextTick(() => renderChart())
})

// 计算DCF估值
function calculateDCF() {
  if (!validateForm()) {
    return
  }
  const { currentFCF, growthRate, forecastYears, discountRate, terminalGrowthRate } = formData
  const cashflowProjection = []
  let fcf = currentFCF
  for (let year = 1; year <= forecastYears; year++) {
    if (year > 1) {
      fcf = fcf * (1 + growthRate / 100)
    }
    const discountFactor = 1 / Math.pow(1 + discountRate / 100, year)
    const presentValue = fcf * discountFactor
    const formula = `${formatCurrency(fcf)}÷(1+${discountRate/100})^${year}`
    cashflowProjection.push({
      fcf: fcf,
      discountFactor: discountFactor,
      presentValue: presentValue,
      formula: formula
    })
  }
  const terminalFCF = fcf * (1 + terminalGrowthRate / 100)
  const terminalValue = terminalFCF / ((discountRate - terminalGrowthRate) / 100)
  const terminalValuePresent = terminalValue / Math.pow(1 + discountRate / 100, forecastYears + 1)
  const presentValueSum = cashflowProjection.reduce((sum, year) => sum + year.presentValue, 0)
  const enterpriseValue = presentValueSum + terminalValuePresent
  const terminalFormula = `${formatCurrency(fcf)}×(1+${terminalGrowthRate/100})÷(${discountRate/100}-${terminalGrowthRate/100})`
  const terminalPresentFormula = `${formatCurrency(terminalValue)}÷(1+${discountRate/100})^${forecastYears+1}`
  const enterpriseValueFormula = `${formatCurrency(presentValueSum)} + ${formatCurrency(terminalValuePresent)}`
  valuationResults.value = {
    enterpriseValue,
    cashflowProjection,
    terminalFCF,
    terminalValue,
    terminalValuePresent,
    terminalFormula,
    terminalPresentFormula,
    enterpriseValueFormula
  }
  showResults.value = true
}

// 验证表单
function validateForm() {
  // 必填项
  if (!formData.currentFCF || formData.growthRate === null || formData.forecastYears === null || formData.discountRate === null || formData.terminalGrowthRate === null) {
    alert('请填写所有必填字段');
    return false;
  }
  // 非负校验
  if (formData.currentFCF <= 0 || formData.growthRate < 0 || formData.forecastYears <= 0 || formData.discountRate <= 0 || formData.terminalGrowthRate < 0) {
    alert('所有输入必须为正数，增长率和永续增长率不能为负');
    return false;
  }
  // 合理范围校验
  if (formData.growthRate > 100 || formData.terminalGrowthRate > 100 || formData.discountRate > 100) {
    alert('增长率、永续增长率、折现率不能超过100%');
    return false;
  }
  // 折现率必须大于永续增长率
  if (formData.discountRate <= formData.terminalGrowthRate) {
    alert('折现率必须大于永续增长率');
    return false;
  }
  return true;
}

// 重置表单
function resetForm() {
  Object.assign(formData, {
    currentFCF: null,
    growthRate: null,
    forecastYears: null,
    discountRate: null,
    terminalGrowthRate: null
  })
  showResults.value = false
}

// 格式化货币
function formatCurrency(value) {
  if (value === null || value === undefined) return '0.00'
  return Number(value).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
}

function saveToHistory() {
  const record = {
    time: new Date().toLocaleString(),
    params: { ...formData },
    result: { ...valuationResults.value }
  }
  let list = JSON.parse(localStorage.getItem('dcf_history') || '[]')
  list.unshift(record)
  localStorage.setItem('dcf_history', JSON.stringify(list))
  historyList.value = list
  alert('已保存到历史记录！')
}

function loadHistory() {
  historyList.value = JSON.parse(localStorage.getItem('dcf_history') || '[]')
  showHistory.value = true
}

function applyHistory(record) {
  Object.assign(formData, record.params)
  valuationResults.value = record.result
  showResults.value = true
  showHistory.value = false
}

function deleteHistory(idx) {
  let list = JSON.parse(localStorage.getItem('dcf_history') || '[]')
  list.splice(idx, 1)
  localStorage.setItem('dcf_history', JSON.stringify(list))
  historyList.value = list
}
</script>

<style scoped>
.dcf-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 2rem 1rem;
  background: linear-gradient(to bottom, #f4f8fb 0%, #fafdff 100%);
  min-height: 100vh;
}

.dcf-header {
  text-align: center;
  margin-bottom: 2rem;
  background: white;
  padding: 2rem;
  border-radius: 18px;
  box-shadow: 0 2px 16px 0 rgba(80,120,200,0.06);
}

.dcf-header h1 {
  font-size: 1.7rem;
  font-weight: 700;
  color: #222;
  margin-bottom: 0.5rem;
}

.dcf-description {
  color: #4b5563;
  font-size: 1rem;
  line-height: 1.6;
}

.dcf-content {
  display: grid;
  gap: 2rem;
}

.input-section, .results-section {
  background: white;
  padding: 2rem;
  border-radius: 18px;
  box-shadow: 0 2px 16px 0 rgba(80,120,200,0.06);
}

.input-section h2, .results-section h2 {
  color: #222;
  margin-bottom: 1.2rem;
  font-size: 1.15rem;
  font-weight: 600;
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.5rem;
  margin-bottom: 2rem;
}

.form-group {
  display: flex;
  flex-direction: column;
}

.form-group label {
  font-weight: 600;
  color: #4b5563;
  margin-bottom: 0.3rem;
  font-size: 0.98rem;
}

.form-input {
  padding: 0.65rem;
  border: 2px solid #e5e7eb;
  border-radius: 10px;
  font-size: 0.98rem;
  transition: border-color 0.2s;
  background: white;
  color: #222;
}

.form-input:focus {
  outline: none;
  border-color: #4f8cff;
}

.form-actions {
  display: flex;
  gap: 1.2rem;
  justify-content: center;
  margin-top: 1.5rem;
}

.btn-main {
  background: linear-gradient(90deg, #4f8cff 0%, #7eb6ff 100%);
  color: white;
  border: none;
  border-radius: 10px;
  font-weight: 600;
  font-size: 1rem;
  padding: 0.65rem 2rem;
  box-shadow: 0 2px 8px 0 rgba(80,120,200,0.06);
  transition: all 0.2s;
}

.btn-main:hover {
  background: linear-gradient(90deg, #2563eb 0%, #4f8cff 100%);
}

.btn-secondary {
  background: #fff;
  color: #2563eb;
  border: 1.5px solid #b6d2ff;
  border-radius: 10px;
  font-weight: 600;
  font-size: 1rem;
  padding: 0.65rem 2rem;
  box-shadow: 0 2px 8px 0 rgba(80,120,200,0.03);
  transition: all 0.2s;
}

.btn-secondary:hover {
  background: #eaf2ff;
}

.results-grid {
  display: flex;
  justify-content: center;
  margin-bottom: 2rem;
}

.result-card.primary {
  background: linear-gradient(120deg, #eaf2ff 0%, #c7e0ff 100%);
  border-radius: 18px;
  box-shadow: 0 2px 16px 0 rgba(80,120,200,0.08);
  padding: 1.5rem 1.5rem 1.2rem 1.5rem;
  text-align: center;
  width: 100%;
  max-width: 100%;
  margin: 0 auto;
}

.result-card.primary h3 {
  color: #2563eb;
  font-size: 1.08rem;
  font-weight: 600;
  margin-bottom: 0.7rem;
}

.result-value-row {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.result-value {
  font-size: 2.1rem;
  font-weight: 700;
  color: #2563eb;
  margin-bottom: 0;
  display: inline-block;
  line-height: 1.1;
}

.result-label {
  font-size: 1.05rem;
  color: #4b5563;
  opacity: 0.85;
  display: inline-block;
  margin-left: 0.2rem;
  vertical-align: baseline;
  line-height: 1.1;
}

.cashflow-table {
  margin-top: 1.1rem;
  background: white;
  border-radius: 16px;
  box-shadow: 0 2px 12px 0 rgba(80,120,200,0.06);
  padding: 1.5rem 1rem 1.5rem 1rem;
}

.cashflow-table h3 {
  color: #222;
  margin-bottom: 1rem;
  font-size: 1.05rem;
  font-weight: 600;
}

.table-container {
  overflow-x: auto;
}

table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  background: white;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 2px 8px 0 rgba(80,120,200,0.04);
  font-size: 0.98rem;
}

th, td {
  padding: 1rem 0.7rem;
  text-align: left;
  border-bottom: 1px solid #e5e7eb;
  color: #222;
}

th {
  background: #f4f8fb;
  font-weight: 600;
  color: #2563eb;
  font-size: 0.98rem;
}

tr:last-child td {
  border-bottom: none;
}

tr:hover {
  background: #fafdff;
}

@media (max-width: 768px) {
  .dcf-container {
    padding: 1rem;
  }
  .form-grid {
    grid-template-columns: 1fr;
  }
  .results-grid {
    flex-direction: column;
  }
  .result-card.primary {
    min-width: unset;
    padding: 1.2rem 0.5rem 1rem 0.5rem;
  }
  .cashflow-table {
    padding: 1rem 0.2rem 1rem 0.2rem;
  }
  table {
    font-size: 0.98rem;
  }
}

.history-modal {
  position: fixed; left:0; top:0; right:0; bottom:0; background:rgba(0,0,0,0.18); z-index:9999; display:flex; align-items:center; justify-content:center;
}
.history-content {
  background:white; border-radius:12px; padding:28px 32px; min-width:340px; box-shadow:0 2px 16px 0 rgba(80,120,200,0.13);
}
.history-content h3 {
  font-size: 1.15rem;
  color: #2563eb;
  margin-bottom: 1.2rem;
}
.history-list {
  list-style: none;
  padding: 0;
  margin: 0 0 1.2rem 0;
  max-height: 320px;
  overflow-y: auto;
}
.history-list li {
  background: #f4f8fb;
  border-radius: 8px;
  margin-bottom: 1rem;
  padding: 0.7rem 1rem 0.7rem 1rem;
  box-shadow: 0 1px 4px 0 rgba(80,120,200,0.04);
}
.history-time {
  color: #888;
  font-size: 0.97rem;
  margin-bottom: 0.2rem;
}
.history-params {
  color: #222;
  font-size: 0.98rem;
  margin-bottom: 0.5rem;
}
.history-btns {
  display: flex;
  gap: 0.7rem;
}
.btn-hist {
  background: #fff;
  color: #2563eb;
  border: 1.2px solid #b6d2ff;
  border-radius: 7px;
  font-size: 0.98rem;
  padding: 0.3rem 1.1rem;
  margin-right: 0.2rem;
  cursor: pointer;
  transition: all 0.2s;
}
.btn-hist:hover {
  background: #eaf2ff;
}
.btn-hist-del {
  color: #e53e3e;
  border-color: #fbb6b6;
}
.btn-hist-close {
  margin-top: 1.2rem;
  width: 100%;
}

.result-title {
  color: #2563eb;
  font-size: 1.08rem;
  font-weight: 600;
  margin-right: 1.1rem;
  display: inline-block;
}
</style> 